<html>
<head><meta charset="utf-8"><title>trait bounds on const fn · t-compiler/const-eval · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/index.html">t-compiler/const-eval</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html">trait bounds on const fn</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="183921727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183921727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183921727">(Dec 20 2019 at 09:50)</a>:</h4>
<p>We can start experimenting with <code>const fn</code> that have trait bounds on their generic parameters</p>



<a name="183921744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183921744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183921744">(Dec 20 2019 at 09:51)</a>:</h4>
<p>see <a href="https://github.com/rust-lang/rfcs/pull/2632#issuecomment-567699174" target="_blank" title="https://github.com/rust-lang/rfcs/pull/2632#issuecomment-567699174">https://github.com/rust-lang/rfcs/pull/2632#issuecomment-567699174</a> for the T-lang post</p>



<a name="183921795"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183921795" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183921795">(Dec 20 2019 at 09:52)</a>:</h4>
<p>This does not mean the current design is endorsed or can be stabilized without the RFC actually finishing, but it allows gated experimentation so we can hammer out the last kinks in the RFC</p>



<a name="183921848"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183921848" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183921848">(Dec 20 2019 at 09:53)</a>:</h4>
<p>I propse that <code>?const Trait</code> bounds are the first component of the RFC to get implemented</p>



<a name="183921896"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183921896" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183921896">(Dec 20 2019 at 09:53)</a>:</h4>
<p>I believe this would allow us to retire the <code>const_fn</code> feature gate once and for all, because there are no more features gated under it without the feature also having its own feature gate</p>



<a name="183921973"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183921973" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183921973">(Dec 20 2019 at 09:54)</a>:</h4>
<p>So basically on nightly, if you enable <code>const_fn</code>, you can declare trait bounds <code>T: Trait</code> on const fns, but you can't use them for anything but static dispatch to get associated constants and types (or methods, but not call said methods)</p>



<a name="183922019"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922019" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922019">(Dec 20 2019 at 09:55)</a>:</h4>
<p>This is exactly what <code>?const Trait</code> bounds do as per the RFC: <a href="https://github.com/oli-obk/rfcs/blob/const_generic_const_fn_bounds/text/0000-const-generic-const-fn-bounds.md#const-opt-out" target="_blank" title="https://github.com/oli-obk/rfcs/blob/const_generic_const_fn_bounds/text/0000-const-generic-const-fn-bounds.md#const-opt-out">https://github.com/oli-obk/rfcs/blob/const_generic_const_fn_bounds/text/0000-const-generic-const-fn-bounds.md#const-opt-out</a></p>



<a name="183922110"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922110" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922110">(Dec 20 2019 at 09:56)</a>:</h4>
<p>After this change, using plain <code>T: Trait</code> bounds (other than <code>Sized</code>, which is stable) on const fns will become a hard error.</p>



<a name="183922167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922167">(Dec 20 2019 at 09:57)</a>:</h4>
<p>As a parallel step, we can implement <code>impl const Trait</code>, requiring const fn checks for all methods on the impl.</p>



<a name="183922243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922243">(Dec 20 2019 at 09:58)</a>:</h4>
<p>Following that we can implement logic to allow actually calling e.g. <code>i32::add</code> at compile-time</p>



<a name="183922267"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922267" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922267">(Dec 20 2019 at 09:59)</a>:</h4>
<p>and then as a final step we implement calling methods on generic parametes in const fns</p>



<a name="183922293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922293">(Dec 20 2019 at 09:59)</a>:</h4>
<p>These four steps should be separate PRs and may even be split up further to separate the parser changes from the logic changes</p>



<a name="183922833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922833">(Dec 20 2019 at 10:07)</a>:</h4>
<p>I have started a hack.md at <a href="https://hackmd.io/@oli-obk/generic_trait_bounds_on_const_fn" target="_blank" title="https://hackmd.io/@oli-obk/generic_trait_bounds_on_const_fn">https://hackmd.io/@oli-obk/generic_trait_bounds_on_const_fn</a></p>



<a name="183922903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922903">(Dec 20 2019 at 10:08)</a>:</h4>
<p>Lets do an experiment and try to keep this document up to date with our plan</p>



<a name="183922942"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183922942" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183922942">(Dec 20 2019 at 10:09)</a>:</h4>
<p>so we can always discuss here or on the hackmd comments, but then lift the result of these discussions back to the hackmd content</p>



<a name="183923176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lqd <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923176">(Dec 20 2019 at 10:12)</a>:</h4>
<p>do you want to start with <code>T: ?const Trait</code> because it's "not yet universally clear if it's a good idea" and validate/reject that hypothesis quickly ?</p>



<a name="183923429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923429">(Dec 20 2019 at 10:17)</a>:</h4>
<p>no, because we want <em>some</em> scheme like that, and we already do have that scheme on nightly essentially</p>



<a name="183923480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923480">(Dec 20 2019 at 10:18)</a>:</h4>
<p>If we take away this scheme without a replacement, that will cause lots of churn (likely we can't boostrap anymore)</p>



<a name="183923625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lqd <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923625">(Dec 20 2019 at 10:20)</a>:</h4>
<p>hum ok, interesting, thanks oli</p>



<a name="183923635"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923635" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923635">(Dec 20 2019 at 10:20)</a>:</h4>
<p>It's the only proposed syntax that I know of, so we may as well use it even if it's a controversial feature</p>



<a name="183923669"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923669" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923669">(Dec 20 2019 at 10:21)</a>:</h4>
<p>the feature is already implemented, we just need to change its syntax. We could use an attribute for it, but that seems not strictly better</p>



<a name="183923738"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923738" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923738">(Dec 20 2019 at 10:22)</a>:</h4>
<p>This gave me an idea. I updated the hackmd to reflect that we should just add this syntax and wait for a boostrap bump. That way we can change the syntax with zero churn</p>



<a name="183923772"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/183923772" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#183923772">(Dec 20 2019 at 10:22)</a>:</h4>
<p>we could even add a lint to give users the time between the syntax addition and the boostrap bump to migrate</p>



<a name="184199888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/184199888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#184199888">(Dec 25 2019 at 03:18)</a>:</h4>
<p>I don't think lints for nightly migration is necessary</p>



<a name="184199895"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/184199895" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#184199895">(Dec 25 2019 at 03:18)</a>:</h4>
<p>and I'd rather avoid the technical debt it comes with</p>



<a name="184199986"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/184199986" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#184199986">(Dec 25 2019 at 03:20)</a>:</h4>
<p>Also, I'd like to see <code>allow_internal_unstable(...)</code> not work for this</p>



<a name="184200002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/184200002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#184200002">(Dec 25 2019 at 03:20)</a>:</h4>
<p>(and it should not be possible to smuggle generics in even via intermediary associated constants)</p>



<a name="184200009"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/184200009" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#184200009">(Dec 25 2019 at 03:21)</a>:</h4>
<p>Also, any syntax we add should be pre-expansion gated</p>



<a name="184697940"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/184697940" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#184697940">(Jan 03 2020 at 01:06)</a>:</h4>
<p>I implemented the syntax in <a href="https://github.com/rust-lang/rust/issues/67820" target="_blank" title="https://github.com/rust-lang/rust/issues/67820">#67820</a>. I think I got the pre-expansion gating right. This PR has both the <code>?const</code> syntax and the <code>impl const Trait</code>, since they both end up in a single field in<code>TraitRef</code>. I could split them up without too much effort, but I didn't see the comment above about separating the two syntax PRs before it was too late.</p>



<a name="184697952"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/184697952" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#184697952">(Jan 03 2020 at 01:07)</a>:</h4>
<p>Still coming out of a holiday-induced torpor.</p>



<a name="185432522"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185432522" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185432522">(Jan 12 2020 at 12:27)</a>:</h4>
<p><span class="user-mention" data-user-id="124288">@oli</span> Adding a field to <code>Predicate::Trait</code> doesn't increase its size, and doing that feels better than adding a field for all <code>TraitRef</code>s. By the time something appears in a <code>Predicate</code>, we need to know if the trait impl is <code>const</code> or not, not just if <code>?const</code> appears on  the bounds (I think you were alluding to this in your GH comment). Changing how <code>?const</code> is stored in the AST/HIR could make this easier.</p>
<p>Specifically, I want <code>?const</code> to be a <a href="https://github.com/rust-lang/rust/blob/0b6c116a84fb1dbb60b5870291f5d7df808c280d/src/libsyntax/ast.rs#L272" target="_blank" title="https://github.com/rust-lang/rust/blob/0b6c116a84fb1dbb60b5870291f5d7df808c280d/src/libsyntax/ast.rs#L272"><code>TraitBoundModifier</code></a> variant and <code>impl const</code> to be a field on <a href="https://github.com/rust-lang/rust/blob/0b6c116a84fb1dbb60b5870291f5d7df808c280d/src/libsyntax/ast.rs#L2617" target="_blank" title="https://github.com/rust-lang/rust/blob/0b6c116a84fb1dbb60b5870291f5d7df808c280d/src/libsyntax/ast.rs#L2617"><code>ItemKind::Impl</code></a>. I didn't do this in <a href="https://github.com/rust-lang/rust/issues/67820" target="_blank" title="https://github.com/rust-lang/rust/issues/67820">#67820</a> since <code>ItemKind::Impl</code> is matched exhaustively in a lot of places, which makes changing it a pain.</p>



<a name="185432727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185432727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185432727">(Jan 12 2020 at 12:34)</a>:</h4>
<p>Also, I was thinking that trait bounds on <code>const fn</code> should only become<code>const</code> if <code>#![feature(const_trait_impl)]</code> is enabled. This would preserve the meaning of <code>const fn foo&lt;T: TraitWithAssocConst&gt;() {}</code> in code using <code>#![feature(const_fn)]</code> today. I think it's premature to break such code since RFC 2632 hasn't been accepted yet, but maybe you disagree.</p>



<a name="185432927"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185432927" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185432927">(Jan 12 2020 at 12:40)</a>:</h4>
<p>I don't have as much time to work on rustc as I did last year, but I'll keep moving in this direction. I'll try to coordinate with you a bit better in the future.</p>



<a name="185471053"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185471053" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185471053">(Jan 13 2020 at 07:45)</a>:</h4>
<p>We are allowed to break the <code>const_fn</code> feature. In fact I hope we can eliminate it entirely after <code>?const</code> is implemented</p>



<a name="185471166"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185471166" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185471166">(Jan 13 2020 at 07:47)</a>:</h4>
<p>You can make it a TraitBoundModifier variant if you explicitly make <code>?const ?Trait</code> a hard error (and <code>??const Trait</code> as well)</p>



<a name="185471206"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185471206" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185471206">(Jan 13 2020 at 07:48)</a>:</h4>
<p>That's OK to do because opt outs are unstable except for <code>Sized</code></p>



<a name="185471214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185471214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185471214">(Jan 13 2020 at 07:48)</a>:</h4>
<p>And all <code>Sized</code> impls are <code>const</code></p>



<a name="185471251"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185471251" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185471251">(Jan 13 2020 at 07:49)</a>:</h4>
<p>Wrt ItemKind, seems unfortunate to add another field to this insanely big variant, but i don't see a better way, too</p>



<a name="185474210"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185474210" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185474210">(Jan 13 2020 at 08:43)</a>:</h4>
<p>If you want the breaking change to be less painful for nightly users you can keep allowing it under <code>const_fn</code> and we'll deprecate the feature in a separate PR</p>



<a name="185474275"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/185474275" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#185474275">(Jan 13 2020 at 08:44)</a>:</h4>
<p>Wrt time to work on it. Take all the time you need, there's no pressure. It's awesome that you are moving this forward!</p>



<a name="186333701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186333701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186333701">(Jan 22 2020 at 21:38)</a>:</h4>
<p>I would say the "easy" part is now implemented (parsing and lowering). I was wondering if <span class="user-mention" data-user-id="124288">@oli</span> had any advice for the trait solving aspect. My conception was the following: use the trait solver to solve for the impl or bound that provides each method call during const-checking, then see if that impl is a <code>impl const Trait</code> or if the bound which provides is a <code>const</code> one (i.e. doesn't have the opt-out). As you can probably intuit, I don't have a great idea for what stage we associate method calls with inherent impls/generic bounds, so any pointers to code where similar things are done would be great.</p>



<a name="186334348"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186334348" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186334348">(Jan 22 2020 at 21:46)</a>:</h4>
<p>There's also the task of deprecating the current semantics for unadorned bounds in <code>const fn</code> and directing people to use <code>?const</code>. I had mentioned that it would be possible to have <code>#![feature(const_fn)]</code> preserve the existing semantics for trait bounds at the cost of slightly increased complexity in the const checker. I would have liked to have removed <code>qualify_min_const_fn</code> entirely by this point; it would have made the back-compat idea easier since <code>#![feature(const_fn)]</code> wouldn't serve double duty. Since that pass still exists, I think we should not try to do the back-compat thing.</p>



<a name="186397436"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186397436" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186397436">(Jan 23 2020 at 15:08)</a>:</h4>
<p>I think as  a first step we're going to need a query <code>is_const_impl</code> because otherwise we lose this information cross crate</p>



<a name="186397532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186397532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186397532">(Jan 23 2020 at 15:09)</a>:</h4>
<p>As a second step I'd recommend to implement a check that enforces that all functions inside an <code>impl const Trait</code> adhere to <code>const fn</code></p>



<a name="186397715"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186397715" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186397715">(Jan 23 2020 at 15:11)</a>:</h4>
<p>and only then do the trait solving (which as you correctly inferred is the hardest part here)</p>



<a name="186397776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186397776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186397776">(Jan 23 2020 at 15:11)</a>:</h4>
<p>you can still split this step into two</p>



<a name="186397923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186397923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186397923">(Jan 23 2020 at 15:12)</a>:</h4>
<p>actually... maybe even into three</p>



<a name="186397999"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186397999" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186397999">(Jan 23 2020 at 15:13)</a>:</h4>
<p>so the first substep could be to permit monomorphic calls to trait methods. So <code>const FOO: u32 = 1u32.add(2u32);</code></p>



<a name="186398084"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186398084" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186398084">(Jan 23 2020 at 15:14)</a>:</h4>
<p>and here's the point where I also don't know what parts of the compiler you need to touch</p>



<a name="186398148"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186398148" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186398148">(Jan 23 2020 at 15:15)</a>:</h4>
<p>the second substep would be to allow having trait bounds on generics of const fn and calling them inside the const fn</p>



<a name="186398190"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186398190" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186398190">(Jan 23 2020 at 15:15)</a>:</h4>
<p>the fourth substep would be to permit calls to generic const fn by doing the trait solving that you hinted at in your message</p>



<a name="186398508"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186398508" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186398508">(Jan 23 2020 at 15:19)</a>:</h4>
<blockquote>
<p>so the first substep could be to permit monomorphic calls to trait methods. So <code>const FOO: u32 = 1u32.add(2u32);</code></p>
</blockquote>
<p>Note: do not change libcore/libstd yet, we first need a <code>rustc_const_unstable</code> scheme for that</p>



<a name="186442447"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/186442447" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#186442447">(Jan 23 2020 at 22:17)</a>:</h4>
<p><span class="user-mention" data-user-id="124288">@oli</span> Sounds like a good plan. I'll work on the first two when I have time and try and find someone who's familiar with the trait solver API to point me in the right direction.</p>



<a name="187426581"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/trait%20bounds%20on%20const%20fn/near/187426581" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/trait.20bounds.20on.20const.20fn.html#187426581">(Feb 05 2020 at 05:24)</a>:</h4>
<p>The first two are done in <a href="https://github.com/rust-lang/rust/issues/68847" target="_blank" title="https://github.com/rust-lang/rust/issues/68847">#68847</a>. It's nice and small for now, although the test suite isn't complete and I haven't dealt with <code>rustc_const_unstable</code>. I've also looked into the type param part a bit more. My tentative plan is to make the trait solver/method prober return the "root predicate" where it found a trait method. Still not sure how easy/hard this will be. An alternative is to have the trait solver actually consider the constness of impls/bounds when solving, and have type checking run in the current, const-unaware mode and const-checking ran in the const-aware mode.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>